package com.kye.express.business.help.search;

import android.content.Context;
import android.content.Intent;
import android.databinding.DataBindingUtil;
import android.net.NetworkInfo;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v7.widget.LinearLayoutManager;
import android.text.TextUtils;
import android.view.View;
import android.view.inputmethod.EditorInfo;

import com.afollestad.materialdialogs.DialogAction;
import com.afollestad.materialdialogs.MaterialDialog;
import com.beloo.widget.chipslayoutmanager.ChipsLayoutManager;
import com.jakewharton.rxbinding2.view.RxView;
import com.jakewharton.rxbinding2.widget.RxTextView;
import com.jakewharton.rxbinding2.widget.TextViewEditorActionEvent;
import com.kye.base.DebounceObservableTransformer;
import com.kye.base.Logger;
import com.kye.base.utils.NetworkMonitorUtils;
import com.kye.express.R;
import com.kye.express.business.base.BaseAppCompatActivity;
import com.kye.express.databinding.ActivityHelpSearchBinding;
import com.kye.express.utils.InputUtils;
import com.kye.express.utils.NetUtils;
import com.kye.express.view.ToastManager;
import com.kye.model.bean.OpenApiResult;
import com.kye.model.bean.help.ResultQueryHelpHotListBean;
import com.kye.model.bean.help.ResultQueryHelpListBean;
import com.kye.model.constant.Constants;

import java.util.Arrays;
import java.util.List;
import java.util.concurrent.TimeUnit;

import io.reactivex.Observer;
import io.reactivex.Single;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Consumer;
import io.reactivex.functions.Function;
import io.reactivex.functions.Predicate;
import io.reactivex.schedulers.Schedulers;
import me.drakeet.multitype.MultiTypeAdapter;

/**
 * 帮助-搜索 Activity
 * <p>
 * Created by SkyYu on 2018/1/9
 */
public class HelpSearchActivity extends BaseAppCompatActivity implements HelpSearchContract.HelpSearchView {

    private final static String TAG = HelpSearchActivity.class.getSimpleName();

    private ActivityHelpSearchBinding mBinding;
    private HelpSearchContract.HelpSearchPresenter mPresenter;
    private MultiTypeAdapter mSearchHistoryAdapter;
    private MultiTypeAdapter mSearchResultAdapter;

    private String ids = "";
    private int classId = 0;
    private int num = 100;

    public static void startActivity(Context context) {
        Intent intent = new Intent(context, HelpSearchActivity.class);
        context.startActivity(intent);
    }

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        initView();
        initEvent();
        initData();
    }

    private void initView() {
        initBinding();
        initPresenter();
        initSearchResultView();
        initSearchHistoryView();
    }

    private void initData() {
        mBinding.statusLayoutHelpSearch.showLoadingView();
        setEmptyViewData();
        requestToHot();
    }

    private void initEvent() {
        RxTextView.editorActionEvents(mBinding.recyclerHelpSearchInput)
                .compose(bindToLifecycleDestroy())
                .subscribeOn(AndroidSchedulers.mainThread())
                .observeOn(Schedulers.computation())
                .filter(new Predicate<TextViewEditorActionEvent>() {
                    @Override
                    public boolean test(TextViewEditorActionEvent textViewEditorActionEvent) throws Exception {
                        return textViewEditorActionEvent.actionId() == EditorInfo.IME_ACTION_SEARCH;
                    }
                })
                .filter(new Predicate<TextViewEditorActionEvent>() {
                    @Override
                    public boolean test(TextViewEditorActionEvent textViewEditorActionEvent) throws Exception {
                        return !TextUtils.isEmpty(mBinding.recyclerHelpSearchInput.getText().toString());
                    }
                })
                .map(new Function<TextViewEditorActionEvent, String>() {
                    @Override
                    public String apply(TextViewEditorActionEvent textViewEditorActionEvent) throws Exception {
                        return mBinding.recyclerHelpSearchInput.getText().toString();
                    }
                })
                .doOnNext(new Consumer<String>() {
                    @Override
                    public void accept(String s) throws Exception {
                        Logger.d("input : " + s);
                    }
                })
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<String>() {

                    @Override
                    public void onSubscribe(Disposable d) {

                    }

                    @Override
                    public void onNext(String queryData) {
                        if (NetUtils.isNetworkAvailable(HelpSearchActivity.this)) {
                            mBinding.statusLayoutHelpSearch.showLoadingView();
                            Single.timer(1, TimeUnit.SECONDS)
                                    .compose(bindToLifecycle())
                                    .subscribe((Long)->{
                                                mPresenter.requestToQueryHelpInfoList(ids, classId, num, queryData);
                                                mPresenter.saveQueryDataObservable(queryData);
                                            }
                                            , Throwable::printStackTrace
                                    );
                        } else {
                            ToastManager.show(HelpSearchActivity.this, getString(R.string.common_net_error));
                        }
                        InputUtils.hideSoftInput(HelpSearchActivity.this);
                    }

                    @Override
                    public void onError(Throwable e) {
                        InputUtils.hideSoftInput(HelpSearchActivity.this);
                    }

                    @Override
                    public void onComplete() {
                        InputUtils.hideSoftInput(HelpSearchActivity.this);
                    }
                });

        RxView.clicks(mBinding.recyclerHelpSearchClear)
                .compose(new DebounceObservableTransformer<>())
                .compose(this.bindToLifecycleDestroy())
                .subscribe(new Consumer<Object>() {
                    @Override
                    public void accept(Object o) throws Exception {
                        new MaterialDialog.Builder(HelpSearchActivity.this)
                                .content("确认删除全部历史记录")
                                .negativeText("取消")
                                .positiveText("确认")
                                .onNegative(new MaterialDialog.SingleButtonCallback() {
                                    @Override
                                    public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
                                        dialog.dismiss();
                                    }
                                })
                                .onPositive(new MaterialDialog.SingleButtonCallback() {
                                    @Override
                                    public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
                                        mBinding.statusLayoutHelpSearch.showLoadingView();
                                        mPresenter.clearSearchHistoryData();
                                    }
                                }).show();
                    }
                });

        RxView.clicks(mBinding.recyclerHelpSearchCancel)
                .compose(new DebounceObservableTransformer<>())
                .compose(this.bindToLifecycleDestroy())
                .subscribe(new Consumer<Object>() {
                    @Override
                    public void accept(Object o) throws Exception {
                        mBinding.recyclerHelpSearchInput.setText("");
                        finish();
                    }
                });

        /*
         * 监听输入内容，为空时显示最热和历史记录
         */
        RxTextView.textChanges(mBinding.recyclerHelpSearchInput)
                .compose(bindToLifecycleDestroy())
                .map(new Function<CharSequence, Boolean>() {
                    @Override
                    public Boolean apply(CharSequence charSequence) throws Exception {
                        return TextUtils.isEmpty(charSequence);
                    }
                })
                .subscribe(new Consumer<Boolean>() {
                    @Override
                    public void accept(Boolean isEmpty) throws Exception {
                        if(isEmpty){
                            mBinding.statusLayoutHelpSearch.showContentView();
                            mBinding.setToggleResult(false);
                            InputUtils.hideSoftInput(HelpSearchActivity.this);
                        }
                    }
                });
    }

    private void initBinding() {
        mBinding = DataBindingUtil.setContentView(this, R.layout.activity_help_search);
    }

    private void initPresenter() {
        mPresenter = new HelpSearchContract.HelpSearchPresenter(this);
        mPresenter.bind(this);
    }

    private void initSearchHotView(String result) {
        ChipsLayoutManager spanLayoutManagerHot = ChipsLayoutManager.newBuilder(this)
                .setOrientation(ChipsLayoutManager.HORIZONTAL)
                .build();
        mBinding.recyclerHelpSearchHot.setLayoutManager(spanLayoutManagerHot);
        MultiTypeAdapter mSearchHotAdapter = new MultiTypeAdapter();
        mSearchHotAdapter.register(String.class, new HelpSearchLabelItemViewBinder(new HelpSearchLabelItemViewBinder.OnItemListener() {
            @Override
            public void onItemClicked(String item) {
                onLabelClicked(item);
            }
        }));
        String[] searchHotKeywords = result.split(",");
        mSearchHotAdapter.setItems(Arrays.asList(searchHotKeywords));
        mBinding.recyclerHelpSearchHot.setAdapter(mSearchHotAdapter);
    }

    private void initSearchHistoryView() {
        ChipsLayoutManager spanLayoutManagerHistory = ChipsLayoutManager.newBuilder(this)
                .setOrientation(ChipsLayoutManager.HORIZONTAL)
                .build();
        mBinding.recyclerHelpSearchHistory.setLayoutManager(spanLayoutManagerHistory);
        mSearchHistoryAdapter = new MultiTypeAdapter();
        mSearchHistoryAdapter.register(String.class, new HelpSearchLabelItemViewBinder(new HelpSearchLabelItemViewBinder.OnItemListener() {
            @Override
            public void onItemClicked(String item) {
                onLabelClicked(item);
            }
        }));
        mBinding.recyclerHelpSearchHistory.setAdapter(mSearchHistoryAdapter);
        mPresenter.updateSearchHistoryData();
    }

    private void initSearchResultView() {
        mBinding.recyclerHelpSearchResult.setLayoutManager(new LinearLayoutManager(this));
        mSearchResultAdapter = new MultiTypeAdapter();
        mSearchResultAdapter.register(ResultQueryHelpListBean.class, new HelpSearchResultItemViewBinder(this));
        mBinding.recyclerHelpSearchResult.setAdapter(mSearchResultAdapter);
    }

    private void setEmptyViewData() {
        mBinding.llEmptyCustom.tvEmptyText.setText( "暂无相关数据");
        mBinding.llEmptyCustom.ivEmptyImage.setImageResource(R.drawable.icon_help_search_nodata);
        mBinding.llEmptyCustom.btEmptyRetry.setVisibility(View.GONE);
    }

    private void requestToHot() {
        NetworkMonitorUtils.networkObservable(this)
                .compose(bindToLifecycleDestroy())
                .map((connectivity) -> {
                    NetworkInfo.State state = connectivity.getState();
                    switch (state) {
                        case CONNECTED:
                        case CONNECTING:
                            return true;
                        case DISCONNECTED:
                        case DISCONNECTING:
                            return false;
                        default:
                            return false;
                    }
                })
                .subscribe((Boolean) -> {
                    if (Boolean) {
                        mPresenter.requestTpQueryHotSearch();
                    } else {
                        mBinding.statusLayoutHelpSearch.showErrorNetworkView();
                        ToastManager.show(this, getString(R.string.common_net_error));
                    }
                });
    }

    /**
     * 热门搜索 成功回调
     */
    @Override
    public void onHotSuccess(OpenApiResult<ResultQueryHelpHotListBean> result) {
        if (result != null) {
            if (result.getCode() == Constants.ResponseCode_SUCCESS) {
                mBinding.statusLayoutHelpSearch.showContentView();
                initSearchHotView(result.getData().getKeyword());
                mBinding.setToggleResult(false);
            } else {
                ToastManager.show(this,result.getMsg());
            }
        } else {
            Logger.d(TAG + "onHotSuccess - bean is null");
        }
    }

    /**
     * 热门搜索 ApiError回调
     */
    @Override
    public void onHotApiError(OpenApiResult<ResultQueryHelpHotListBean> result, int code, String msg) {
        mBinding.statusLayoutHelpSearch.showErrorServerView();
        ToastManager.show(this, msg);
        Logger.d(TAG + " - onHotApiError - result:" + result + ",code:" + code + ",msg:" + msg);
    }

    /**
     * 热门搜索 OtherError回调
     */
    @Override
    public void onHotOtherError(Throwable e) {
        mBinding.statusLayoutHelpSearch.showErrorNetworkView();
        ToastManager.show(this, getString(R.string.common_net_error));
        Logger.d(TAG + " - refreshInitOtherError : " + e.getMessage());
        e.printStackTrace();
    }

    /**
     * 关键词搜索 成功回调
     */
    @Override
    public void onSearchSuccess(OpenApiResult<List<ResultQueryHelpListBean>> result) {
        if (result != null) {
            if (result.getCode() == Constants.ResponseCode_SUCCESS) {
                if(result.getData().size() > 0){
                    mBinding.setToggleResult(true);
                    mBinding.statusLayoutHelpSearch.showContentView();
                    mSearchResultAdapter.setItems(result.getData());
                    mSearchResultAdapter.notifyDataSetChanged();
                }else{
                    mBinding.statusLayoutHelpSearch.showEmptyView();
                }
            } else {
                ToastManager.show(this,result.getMsg());
            }
        } else {
            Logger.d(TAG + "onSearchSuccess - bean is null");
        }
    }

    /**
     * 关键词搜索 ApiError回调
     */
    @Override
    public void onSearchApiError(OpenApiResult<List<ResultQueryHelpListBean>> result, int code, String msg) {
        mBinding.statusLayoutHelpSearch.showErrorServerView();
        ToastManager.show(this, msg);
        Logger.d(TAG + " - onSearchApiError - result:" + result + ",code:" + code + ",msg:" + msg);
    }

    /**
     * 关键词搜索 OtherError回调
     */
    @Override
    public void onSearchOtherError(Throwable e) {
        mBinding.statusLayoutHelpSearch.showErrorNetworkView();
        ToastManager.show(this, getString(R.string.common_net_error));
        Logger.d(TAG + " - refreshInitOtherError : " + e.getMessage());
        e.printStackTrace();
    }

    /**
     * 保存到搜索历史记录集合 成功回调
     */
    @Override
    public void onSearchHistorySuccess(List<String> data) {
        mSearchHistoryAdapter.setItems(data);
        mSearchHistoryAdapter.notifyDataSetChanged();
    }

    /**
     * 保存到搜索历史记录集合 失败回调
     */
    @Override
    public void onSearchHistoryFailed(Throwable e) {
        Logger.d(TAG + "onSearchHistoryFailed : " + e.getMessage());
        e.printStackTrace();
    }

    @Override
    public void onLabelClicked(String item) {
        mBinding.statusLayoutHelpSearch.showLoadingView();
        InputUtils.hideSoftInput(this);
        mBinding.recyclerHelpSearchInput.setText(item);
        mBinding.recyclerHelpSearchInput.setSelection(item.length());
        mBinding.recyclerHelpSearchInput.clearFocus();
        Single.timer(1, TimeUnit.SECONDS)
                .compose(bindToLifecycle())
                .subscribe((Long)->{
                            mPresenter.requestToQueryHelpInfoList(ids, classId, num, item);
                            mPresenter.saveQueryDataObservable(item);
                        }
                        , Throwable::printStackTrace
                );
    }
}